package com.competition.jingdong;

import java.util.LinkedList;
import java.util.Objects;
import java.util.PriorityQueue;

public class Room implements Comparable{
    Position start;
    int sx;
    int sy;
    int sz;
    long volume;
    Room(){

    }
    Room(Position position,int ox,int oy,int oz)
    {
        this.start=position;
        this.sx=ox;
        this.sy=oy;
        this.sz=oz;
        volume=ox*oy*oz;

    }
    //Room排序按体积降序排
    @Override
    public int compareTo(Object o) {
        if(this.volume>((Room)o).volume)
            return -1;
        else
            return 1;
    }
    //判断一个商品能否放入当前room中,能则返回end position不能则返回null
    Position ifAccommodateOnOrder(Sku sku)
    {
        if(this.volume<sku.volume)
            return null;
        if(this.sx<sku.length || this.sy<sku.weight || this.sz<sku.high)
            return null;
        return new Position(this.start.x+sku.length,this.start.y+sku.weight,this.start.z+sku.high);
    }
    Position ifAccommodate3(Sku sku)
    {
        Position p;
        if((p=ifAccommodate(sku)) !=null)
        {
            return p;
        }
        else
        {
            int max = Math.max(sx,Math.max(sy,sz));
            int min = Math.min(sx,Math.min(sy,sz));
            int mid = sx>sy? (sx>sz?(sy>sz?sy:sz):sx):(sy>sz?(sx>sz?sx:sz):sy);
            if(sku.length>max && max>=(int)Math.ceil(0.9*sku.length)  && sku.weight>mid && mid>=(int)Math.ceil(0.9*sku.weight) && sku.high>min && min>=(int)Math.ceil(0.9*sku.high))
            {
                return ifAccommodate(new Sku(sku.skuNo,max,mid,min,false));
            }
        }
        return null;
    }
    Position ifAccommodate(Sku sku)
    {
        if(this.volume<sku.volume)
            return null;
        //room中x轴最长
        if(sx>=sku.length)
        {
            // room长宽高和商品相符
            if(sy>=sku.weight && sz>=sku.high)
                return new Position(start.x+sku.length,start.y+sku.weight,start.z+sku.high);
            // 商品需要翻一个身
            if(sy>=sku.high && sz>=sku.weight)
                return new Position(start.x+sku.length,start.y+sku.high,start.z+sku.weight);
        }
        //y轴最长
        else if(sy >=sku.length)
        {
            if(sx>=sku.weight && sz>=sku.high)
                return new Position(start.x+sku.weight,start.y+sku.length,start.z+sku.high);
            if(sx>=sku.high&&sz>=sku.weight)
                return new Position(start.x+sku.high,start.y+sku.length,start.z+sku.weight);
        }
        //z轴最长时
        else if(sz>=sku.length)
        {
            if(sx>=sku.weight &&sy>=sku.high)
                return new Position(start.x+sku.weight,start.y+sku.high,start.z+sku.length);
            if(sx>=sku.high && sy>=sku.weight)
                return new Position(start.x+sku.high,start.y+sku.weight,start.z+sku.length);
        }
        return null;
    }
    LinkedList<Room> mergeUD(Room r2, LinkedList<Room> list)
    {
        //this在上,this>r2:
        if(r2.start.z+r2.sz == this.start.z && this.start.x<=r2.start.x && this.start.y<=r2.start.y && r2.start.x+r2.sx<=this.start.x +this.sx && r2.start.y+r2.sy<=this.start.y+this.sy)
        {
            r2.sz = this.sz+r2.sz;
            r2.jisuanVolume();
            list.add(r2);
            Room r3 = new Room(this.start,this.sx,r2.start.y-this.start.y,this.sz);
            list.add(r3);
            Room r4 = new Room(new Position(this.start.x,r2.start.y,this.start.z),r2.start.x-this.start.x,r2.sy,this.sz);
            list.add(r4);
            Room r5 = new Room(new Position(r2.start.x+r2.sx,r2.start.y,this.start.z),this.sx-r2.sx-r4.sx,r2.sy,this.sz);
            list.add(r5);
            Room r6 = new Room(new Position(this.start.x,this.start.y+r3.sy+r4.sy,this.start.z),this.sx,this.sy-r3.sy-r4.sy,this.sz);
            list.add(r6);
            return list;
        }
        //this在上,this<r2:
        if(this.start.z == r2.start.z+r2.sz && r2.start.x<=this.start.x && r2.start.y<=this.start.y && this.start.x+this.sx<=r2.start.x +r2.sx && this.start.y+this.sy<=r2.start.y+r2.sy)
        {
            Room r3 = new Room(r2.start,r2.sx,this.start.y-r2.start.y,r2.sz);
            Room r4 = new Room(new Position(r2.start.x,this.start.y,r2.start.z),this.start.x-r2.start.x,this.sy,r2.sz);
            Room r5 = new Room(new Position(this.start.x+this.sx,this.start.y,r2.start.z),r2.sx-this.sx-r4.sx,this.sy,r2.sz);
            Room r6 = new Room(new Position(r2.start.x,r2.start.y+r3.sy+r4.sy,r2.start.z),r2.sx,r2.sy-r3.sy-r4.sy,r2.sz);
            list.add(r3);
            list.add(r4);
            list.add(r5);
            list.add(r6);
            r2.start.x = this.start.x;
            r2.start.y = this.start.y;
            r2.sz+=this.sz;
            r2.jisuanVolume();
            list.add(r2);
            return list;
        }
        //左右大小不一致时:test
        if(this.start.x+this.sx == r2.start.x && r2.start.y>=this.start.y && this.start.y+this.sy>=r2.start.y+r2.sy && r2.start.z>=this.start.z && this.start.z+this.sz>=r2.start.z+r2.sz)
        {
            r2.start.x=this.start.x;
            r2.sx+=this.sx;
            r2.jisuanVolume();
            list.add(r2);
            return list;
        }
        return list;
    }
    boolean merge(Room r2)
    {
        //水平融合
        if(this.start.z == r2.start.z) {
            //水平向上
            if(this.start.x == r2.start.x && r2.start.y+r2.sy == this.start.y && this.sx ==r2.sx && this.sz == r2.sz)
            {
                r2.sy = r2.sy+this.sy;
                r2.jisuanVolume();
                return true;
            }
            //水平向下
            if(this.start.x == r2.start.x && this.start.y+this.sy == r2.start.y && this.sx == r2.sx && this.sz == r2.sz)
            {
                r2.start = this.start;
                r2.sy = this.sy+r2.sy;
                r2.jisuanVolume();
                return true;
            }
            //水平向右融合
            if(this.start.y == r2.start.y && this.start.x+this.sx == r2.start.x && this.sy==r2.sy && this.sz == r2.sz)
            {
                r2.start = this.start;
                r2.sx = this.sx+r2.sx;
                r2.jisuanVolume();
                return true;
            }
            //水平向左
            if(this.start.y == r2.start.y && r2.start.x+r2.sx == this.start.x && this.sy==r2.sy && this.sz == r2.sz)
            {
                r2.sx = this.sx+r2.sx;
                r2.jisuanVolume();
                return true;
            }
        }
        //垂直融合
        else {
            //垂直向下,this在上:
            if(this.start.x==r2.start.x && this.start.y==r2.start.y && r2.start.z+r2.sz == this.start.z && this.sx==r2.sx &&this.sy==r2.sy)
            {
                r2.sz = this.sz+r2.sz;
                r2.jisuanVolume();
                return true;
            }
            //垂直向上,r2在上
            if(this.start.x==r2.start.x && this.start.y==r2.start.y && r2.start.z== this.start.z+this.sz && this.sx==r2.sx &&this.sy==r2.sy)
            {
                r2.start.z = this.start.z;
                r2.sz = this.sz+r2.sz;
                r2.jisuanVolume();
                return true;
            }

        }
        return false;
    }
    //当前长度能容纳的sku个数
    int iflength(Sku sku)
    {
        int length = Math.max(Math.max(sx,sy),sz);
        return length/sku.length;
    }
    //宽度?
    int ifweight(Sku sku)
    {
        int weight = Math.min(Math.max(sx,sy),Math.max(sx,sz));
        return weight/sku.weight;
    }
    //高度
    int ifhigh(Sku sku)
    {
        int high = Math.min(Math.min(sx,sy),sz);
        return high/sku.high;
    }

    void jisuanVolume()
    {
        this.volume = this.sx*this.sy*this.sz;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Room room = (Room) o;
        return sx == room.sx && sy == room.sy && sz == room.sz && volume == room.volume && Objects.equals(start, room.start);
    }

    @Override
    public int hashCode() {
        return Objects.hash(start, sx, sy, sz, volume);
    }

    @Override
    public String toString() {
        return "Room{" +
                "start=" + start +
                ", sx=" + sx +
                ", sy=" + sy +
                ", sz=" + sz +
                ", volume=" + volume +
                '}';
    }
}
